﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;

namespace MiniJSON
{
	// Token: 0x02000042 RID: 66
	public static class Json
	{
		// Token: 0x06000217 RID: 535 RVA: 0x0001146C File Offset: 0x0000F66C
		public static object Deserialize(string json)
		{
			bool flag = json == null;
			object result;
			if (flag)
			{
				result = null;
			}
			else
			{
				result = Json.Parser.Parse(json);
			}
			return result;
		}

		// Token: 0x06000218 RID: 536 RVA: 0x00011494 File Offset: 0x0000F694
		public static string Serialize(object obj)
		{
			return Json.Serializer.Serialize(obj);
		}

		// Token: 0x02000297 RID: 663
		private sealed class Parser : IDisposable
		{
			// Token: 0x06000DD8 RID: 3544 RVA: 0x00048FF0 File Offset: 0x000471F0
			public static bool IsWordBreak(char c)
			{
				return char.IsWhiteSpace(c) || "{}[],:\"".IndexOf(c) != -1;
			}

			// Token: 0x06000DD9 RID: 3545 RVA: 0x0004901E File Offset: 0x0004721E
			private Parser(string jsonString)
			{
				this.json = new StringReader(jsonString);
			}

			// Token: 0x06000DDA RID: 3546 RVA: 0x00049034 File Offset: 0x00047234
			public static object Parse(string jsonString)
			{
				object result;
				using (Json.Parser parser = new Json.Parser(jsonString))
				{
					result = parser.ParseValue();
				}
				return result;
			}

			// Token: 0x06000DDB RID: 3547 RVA: 0x00049070 File Offset: 0x00047270
			public void Dispose()
			{
				this.json.Dispose();
				this.json = null;
			}

			// Token: 0x06000DDC RID: 3548 RVA: 0x00049088 File Offset: 0x00047288
			private Dictionary<string, object> ParseObject()
			{
				Dictionary<string, object> dictionary = new Dictionary<string, object>();
				this.json.Read();
				for (;;)
				{
					Json.Parser.TOKEN nextToken = this.NextToken;
					if (nextToken == Json.Parser.TOKEN.NONE)
					{
						break;
					}
					if (nextToken == Json.Parser.TOKEN.CURLY_CLOSE)
					{
						goto IL_34;
					}
					if (nextToken != Json.Parser.TOKEN.COMMA)
					{
						string text = this.ParseString();
						bool flag = text == null;
						if (flag)
						{
							goto Block_4;
						}
						bool flag2 = this.NextToken != Json.Parser.TOKEN.COLON;
						if (flag2)
						{
							goto Block_5;
						}
						this.json.Read();
						dictionary[text] = this.ParseValue();
					}
				}
				return null;
				IL_34:
				return dictionary;
				Block_4:
				return null;
				Block_5:
				return null;
			}

			// Token: 0x06000DDD RID: 3549 RVA: 0x00049120 File Offset: 0x00047320
			private List<object> ParseArray()
			{
				List<object> list = new List<object>();
				this.json.Read();
				bool flag = true;
				while (flag)
				{
					Json.Parser.TOKEN nextToken = this.NextToken;
					Json.Parser.TOKEN token = nextToken;
					if (token == Json.Parser.TOKEN.NONE)
					{
						return null;
					}
					if (token != Json.Parser.TOKEN.SQUARED_CLOSE)
					{
						if (token != Json.Parser.TOKEN.COMMA)
						{
							object item = this.ParseByToken(nextToken);
							list.Add(item);
						}
					}
					else
					{
						flag = false;
					}
				}
				return list;
			}

			// Token: 0x06000DDE RID: 3550 RVA: 0x00049190 File Offset: 0x00047390
			private object ParseValue()
			{
				Json.Parser.TOKEN nextToken = this.NextToken;
				return this.ParseByToken(nextToken);
			}

			// Token: 0x06000DDF RID: 3551 RVA: 0x000491B0 File Offset: 0x000473B0
			private object ParseByToken(Json.Parser.TOKEN token)
			{
				switch (token)
				{
				case Json.Parser.TOKEN.CURLY_OPEN:
					return this.ParseObject();
				case Json.Parser.TOKEN.SQUARED_OPEN:
					return this.ParseArray();
				case Json.Parser.TOKEN.STRING:
					return this.ParseString();
				case Json.Parser.TOKEN.NUMBER:
					return this.ParseNumber();
				case Json.Parser.TOKEN.TRUE:
					return true;
				case Json.Parser.TOKEN.FALSE:
					return false;
				case Json.Parser.TOKEN.NULL:
					return null;
				}
				return null;
			}

			// Token: 0x06000DE0 RID: 3552 RVA: 0x00049238 File Offset: 0x00047438
			private string ParseString()
			{
				StringBuilder stringBuilder = new StringBuilder();
				this.json.Read();
				bool flag = true;
				while (flag)
				{
					bool flag2 = this.json.Peek() == -1;
					if (flag2)
					{
						break;
					}
					char nextChar = this.NextChar;
					char c = nextChar;
					if (c != '"')
					{
						if (c != '\\')
						{
							stringBuilder.Append(nextChar);
						}
						else
						{
							bool flag3 = this.json.Peek() == -1;
							if (flag3)
							{
								flag = false;
							}
							else
							{
								nextChar = this.NextChar;
								char c2 = nextChar;
								if (c2 <= '\\')
								{
									if (c2 == '"' || c2 == '/' || c2 == '\\')
									{
										stringBuilder.Append(nextChar);
									}
								}
								else if (c2 <= 'f')
								{
									if (c2 != 'b')
									{
										if (c2 == 'f')
										{
											stringBuilder.Append('\f');
										}
									}
									else
									{
										stringBuilder.Append('\b');
									}
								}
								else if (c2 != 'n')
								{
									switch (c2)
									{
									case 'r':
										stringBuilder.Append('\r');
										break;
									case 't':
										stringBuilder.Append('\t');
										break;
									case 'u':
									{
										char[] array = new char[4];
										for (int i = 0; i < 4; i++)
										{
											array[i] = this.NextChar;
										}
										stringBuilder.Append((char)Convert.ToInt32(new string(array), 16));
										break;
									}
									}
								}
								else
								{
									stringBuilder.Append('\n');
								}
							}
						}
					}
					else
					{
						flag = false;
					}
				}
				return stringBuilder.ToString();
			}

			// Token: 0x06000DE1 RID: 3553 RVA: 0x000493CC File Offset: 0x000475CC
			private object ParseNumber()
			{
				string nextWord = this.NextWord;
				bool flag = nextWord.IndexOf('.') == -1;
				object result;
				if (flag)
				{
					long num;
					long.TryParse(nextWord, out num);
					result = num;
				}
				else
				{
					double num2;
					double.TryParse(nextWord, out num2);
					result = num2;
				}
				return result;
			}

			// Token: 0x06000DE2 RID: 3554 RVA: 0x0004941C File Offset: 0x0004761C
			private void EatWhitespace()
			{
				while (char.IsWhiteSpace(this.PeekChar))
				{
					this.json.Read();
					bool flag = this.json.Peek() == -1;
					if (flag)
					{
						break;
					}
				}
			}

			// Token: 0x1700010A RID: 266
			// (get) Token: 0x06000DE3 RID: 3555 RVA: 0x00049460 File Offset: 0x00047660
			private char PeekChar
			{
				get
				{
					return Convert.ToChar(this.json.Peek());
				}
			}

			// Token: 0x1700010B RID: 267
			// (get) Token: 0x06000DE4 RID: 3556 RVA: 0x00049484 File Offset: 0x00047684
			private char NextChar
			{
				get
				{
					return Convert.ToChar(this.json.Read());
				}
			}

			// Token: 0x1700010C RID: 268
			// (get) Token: 0x06000DE5 RID: 3557 RVA: 0x000494A8 File Offset: 0x000476A8
			private string NextWord
			{
				get
				{
					StringBuilder stringBuilder = new StringBuilder();
					while (!Json.Parser.IsWordBreak(this.PeekChar))
					{
						stringBuilder.Append(this.NextChar);
						bool flag = this.json.Peek() == -1;
						if (flag)
						{
							break;
						}
					}
					return stringBuilder.ToString();
				}
			}

			// Token: 0x1700010D RID: 269
			// (get) Token: 0x06000DE6 RID: 3558 RVA: 0x00049500 File Offset: 0x00047700
			private Json.Parser.TOKEN NextToken
			{
				get
				{
					this.EatWhitespace();
					bool flag = this.json.Peek() == -1;
					Json.Parser.TOKEN result;
					if (flag)
					{
						result = Json.Parser.TOKEN.NONE;
					}
					else
					{
						char peekChar = this.PeekChar;
						if (peekChar <= '[')
						{
							switch (peekChar)
							{
							case '"':
								return Json.Parser.TOKEN.STRING;
							case '#':
							case '$':
							case '%':
							case '&':
							case '\'':
							case '(':
							case ')':
							case '*':
							case '+':
							case '.':
							case '/':
								break;
							case ',':
								this.json.Read();
								return Json.Parser.TOKEN.COMMA;
							case '-':
							case '0':
							case '1':
							case '2':
							case '3':
							case '4':
							case '5':
							case '6':
							case '7':
							case '8':
							case '9':
								return Json.Parser.TOKEN.NUMBER;
							case ':':
								return Json.Parser.TOKEN.COLON;
							default:
								if (peekChar == '[')
								{
									return Json.Parser.TOKEN.SQUARED_OPEN;
								}
								break;
							}
						}
						else
						{
							if (peekChar == ']')
							{
								this.json.Read();
								return Json.Parser.TOKEN.SQUARED_CLOSE;
							}
							if (peekChar == '{')
							{
								return Json.Parser.TOKEN.CURLY_OPEN;
							}
							if (peekChar == '}')
							{
								this.json.Read();
								return Json.Parser.TOKEN.CURLY_CLOSE;
							}
						}
						string nextWord = this.NextWord;
						if (!(nextWord == "false"))
						{
							if (!(nextWord == "true"))
							{
								if (!(nextWord == "null"))
								{
									result = Json.Parser.TOKEN.NONE;
								}
								else
								{
									result = Json.Parser.TOKEN.NULL;
								}
							}
							else
							{
								result = Json.Parser.TOKEN.TRUE;
							}
						}
						else
						{
							result = Json.Parser.TOKEN.FALSE;
						}
					}
					return result;
				}
			}

			// Token: 0x04000880 RID: 2176
			private const string WORD_BREAK = "{}[],:\"";

			// Token: 0x04000881 RID: 2177
			private StringReader json;

			// Token: 0x02000412 RID: 1042
			private enum TOKEN
			{
				// Token: 0x04001259 RID: 4697
				NONE,
				// Token: 0x0400125A RID: 4698
				CURLY_OPEN,
				// Token: 0x0400125B RID: 4699
				CURLY_CLOSE,
				// Token: 0x0400125C RID: 4700
				SQUARED_OPEN,
				// Token: 0x0400125D RID: 4701
				SQUARED_CLOSE,
				// Token: 0x0400125E RID: 4702
				COLON,
				// Token: 0x0400125F RID: 4703
				COMMA,
				// Token: 0x04001260 RID: 4704
				STRING,
				// Token: 0x04001261 RID: 4705
				NUMBER,
				// Token: 0x04001262 RID: 4706
				TRUE,
				// Token: 0x04001263 RID: 4707
				FALSE,
				// Token: 0x04001264 RID: 4708
				NULL
			}
		}

		// Token: 0x02000298 RID: 664
		private sealed class Serializer
		{
			// Token: 0x06000DE7 RID: 3559 RVA: 0x00049651 File Offset: 0x00047851
			private Serializer()
			{
				this.builder = new StringBuilder();
			}

			// Token: 0x06000DE8 RID: 3560 RVA: 0x00049668 File Offset: 0x00047868
			public static string Serialize(object obj)
			{
				Json.Serializer serializer = new Json.Serializer();
				serializer.SerializeValue(obj);
				return serializer.builder.ToString();
			}

			// Token: 0x06000DE9 RID: 3561 RVA: 0x00049694 File Offset: 0x00047894
			private void SerializeValue(object value)
			{
				bool flag = value == null;
				if (flag)
				{
					this.builder.Append("null");
				}
				else
				{
					string str;
					bool flag2 = (str = (value as string)) != null;
					if (flag2)
					{
						this.SerializeString(str);
					}
					else
					{
						bool flag3 = value is bool;
						if (flag3)
						{
							this.builder.Append(((bool)value) ? "true" : "false");
						}
						else
						{
							IList anArray;
							bool flag4 = (anArray = (value as IList)) != null;
							if (flag4)
							{
								this.SerializeArray(anArray);
							}
							else
							{
								IDictionary obj;
								bool flag5 = (obj = (value as IDictionary)) != null;
								if (flag5)
								{
									this.SerializeObject(obj);
								}
								else
								{
									bool flag6 = value is char;
									if (flag6)
									{
										this.SerializeString(new string((char)value, 1));
									}
									else
									{
										this.SerializeOther(value);
									}
								}
							}
						}
					}
				}
			}

			// Token: 0x06000DEA RID: 3562 RVA: 0x00049780 File Offset: 0x00047980
			private void SerializeObject(IDictionary obj)
			{
				bool flag = true;
				this.builder.Append('{');
				foreach (object obj2 in obj.Keys)
				{
					bool flag2 = !flag;
					if (flag2)
					{
						this.builder.Append(',');
					}
					this.SerializeString(obj2.ToString());
					this.builder.Append(':');
					this.SerializeValue(obj[obj2]);
					flag = false;
				}
				this.builder.Append('}');
			}

			// Token: 0x06000DEB RID: 3563 RVA: 0x00049838 File Offset: 0x00047A38
			private void SerializeArray(IList anArray)
			{
				this.builder.Append('[');
				bool flag = true;
				foreach (object value in anArray)
				{
					bool flag2 = !flag;
					if (flag2)
					{
						this.builder.Append(',');
					}
					this.SerializeValue(value);
					flag = false;
				}
				this.builder.Append(']');
			}

			// Token: 0x06000DEC RID: 3564 RVA: 0x000498C8 File Offset: 0x00047AC8
			private void SerializeString(string str)
			{
				this.builder.Append('"');
				char[] array = str.ToCharArray();
				char[] array2 = array;
				int i = 0;
				while (i < array2.Length)
				{
					char c = array2[i];
					char c2 = c;
					switch (c2)
					{
					case '\b':
						this.builder.Append("\\b");
						break;
					case '\t':
						this.builder.Append("\\t");
						break;
					case '\n':
						this.builder.Append("\\n");
						break;
					case '\v':
						goto IL_F2;
					case '\f':
						this.builder.Append("\\f");
						break;
					case '\r':
						this.builder.Append("\\r");
						break;
					default:
						if (c2 != '"')
						{
							if (c2 != '\\')
							{
								goto IL_F2;
							}
							this.builder.Append("\\\\");
						}
						else
						{
							this.builder.Append("\\\"");
						}
						break;
					}
					IL_150:
					i++;
					continue;
					IL_F2:
					int num = Convert.ToInt32(c);
					bool flag = num >= 32 && num <= 126;
					if (flag)
					{
						this.builder.Append(c);
					}
					else
					{
						this.builder.Append("\\u");
						this.builder.Append(num.ToString("x4"));
					}
					goto IL_150;
				}
				this.builder.Append('"');
			}

			// Token: 0x06000DED RID: 3565 RVA: 0x00049A44 File Offset: 0x00047C44
			private void SerializeOther(object value)
			{
				bool flag = value is float;
				if (flag)
				{
					this.builder.Append(((float)value).ToString("R"));
				}
				else
				{
					bool flag2 = value is int || value is uint || value is long || value is sbyte || value is byte || value is short || value is ushort || value is ulong;
					if (flag2)
					{
						this.builder.Append(value);
					}
					else
					{
						bool flag3 = value is double || value is decimal;
						if (flag3)
						{
							this.builder.Append(Convert.ToDouble(value).ToString("R"));
						}
						else
						{
							this.SerializeString(value.ToString());
						}
					}
				}
			}

			// Token: 0x04000882 RID: 2178
			private StringBuilder builder;
		}
	}
}
